package mjava.lib;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

public class TdS extends HashMap<String, INFO> implements TdS_itf, Serializable {

	private static final long serialVersionUID = 1L;

	private TdS parente;
	public TdC tdc;
	private int taille;
	private int deplacement;
	
	public TdS(TdS_itf p) {
		super();
		if (p instanceof TdC) {
			tdc = (TdC)p;
			taille = 0;
			// if father table is tdc, then local deplacement is zero
			//deplacement = p.getTaille();
			deplacement = 0;
		}else {
			parente =  (TdS)p;
			taille = 0;
			//deplacement = p.getTaille();
			deplacement = 0;
		}
	}

	public INFO chercher(String n) {
		INFO retour = get(n);
		if (retour == null) {
			if (parente != null){
				retour = parente.chercher(n);
			} else {
				if(tdc.getName().equals(n)) {
					return new INFO(new DTYPE(n, tdc.getTaille()), this.getDeplacement());
				} else {
					retour = tdc.chercher(n);
				}
			}
		}
		return retour;
	}

	public TdC getTdC() {
		return tdc;
	}

	public void inserer(String n, INFO i) {
		put(n, i);
	}

	public String toString() {
		StringBuffer sb = new StringBuffer();
		Set<Map.Entry<String, INFO>> s = entrySet();
		for (Map.Entry<String, INFO> e : s){
			sb.append("; " + e.getKey() + " : " + e.getValue() + '\n');
		
		}
		return sb.toString();
	}
	
	public void addAttrOrVar(String name, INFO var) {
		this.put(name, var);
		this.taille += var.getTaille();
		this.deplacement += var.getTaille();
	}
	
	public int getTaille() {
		return this.taille;
	}
	
	public int getDeplacement() {
		return this.deplacement;
	}


	public Methode checkMethod(String n, String params, String className) {
		return this.tdc.checkMethod(n, params, className);
	}

	public TdC getImportedClass(String Name) {
		return this.tdc.getImportedClass(Name);
	}

	public DTYPE getType() {
		return this.tdc.getType();
	}

	public Attribut checkAttribut(String name) {
		return this.tdc.checkAttribut(name);
	}
	
	public String getName() {
		return this.tdc.getName();
	}

	public Constructeur checkConstructor(String params, String name){
		return this.tdc.checkConstructor(params, name);
	}

	public void setName(String Name) {
		this.tdc.setName(Name);
	}

	public void setSuperClass(TdC superClass) {
		this.tdc.setSuperClass(superClass);
	}
	
	public void sayHello(String hello){
		System.out.println(hello);
	}

	public void addTdCDef(String name, DDEF def) {
		this.tdc.addTdCDef(name, def);
	}

	public void addParams(DPARAMS params) {
		params.setParamsDepl();
		Vector<DPARAM> paramsList = params.getParamList();
		DPARAM par = null;
		for(int i = 0; i < paramsList.size(); i++) {
			par = (DPARAM)paramsList.get(i);
			if(this.get(par.getParamName()) != null) {
				System.out.println("Variable already defined.");
			} else {
				this.put(par.getParamName(), new INFO(par.getParamType(), par.getParamDepl()));
			}
		}
	}

	public void RemoveParams(DPARAMS params) {
		
		Vector<DPARAM> paramsList = params.getParamList();
		DPARAM par = null;
		for(int i = 0; i < paramsList.size(); i++) {
			par = (DPARAM)paramsList.get(i);
			if(this.get(par.getParamName()) == null) {
				System.out.println("Variable not exists.");
			} else {
				this.remove(par.getParamName());
			}
		}
	}
	
	public boolean varFromTdC(String name) {
		boolean res = false;
		if (this.tdc.chercher(name) != null) {
			res = true;
		}
		return res;
	}

	public DTYPE searchType(String name) {
		return this.tdc.searchType(name);
	}
}
